The KNN
algorithm is the first supervised classification model we will study in depth.
Its usefulness comes from its simplicity: to classify a new point, look at the
k closest labeled training points and take a majority vote. This unit covers the
algorithm's place in the taxonomy of ML methods, distance metrics, the critical
choice of k, the equal-vote problem, and how weighted KNN fixes it.
Learning Objectives
Distinguish parametric vs. non-parametric and eager vs. lazy learning paradigms
Explain the 5-step standard KNN algorithm and trace it on toy data
Compute Euclidean, Manhattan, and Minkowski distances between data points
Choose a reasonable k value and justify the choice using the concepts of overfitting vs. underfitting
Describe why feature scaling is mandatory before KNN
Apply distance-weighted KNN to fix the equal-vote problem and explain the weighting variants
2. Theory
2.1 ML Algorithm Taxonomy
Before looking at KNN itself, it helps to place it in the usual algorithm taxonomy. Two distinctions are relevant here: whether an algorithm is parametric or non-parametric, and whether it is a lazy or an eager learner. The two tables below compare them.
Parametric vs. Non-Parametric
Lazy vs. Eager
Dimension
Parametric
Non-Parametric
Parameter count
Fixed, independent of data size
Grows with data size
Assumptions
Strong (linearity, normality, …)
Few / none
Examples
Linear Regression, Logistic Regression, Naïve Bayes
KNN, Decision Trees, Ensembles
Pros
Fast, require less data
Flexible, capture complex patterns
Cons
Too restrictive if assumptions fail
Need more data, computationally costly
Dimension
Lazy Learning
Eager Learning
Training phase
Stores the data only (zero compute)
Builds explicit model immediately
Work happens when?
Prediction time
Training time
Speed: train
Fast
Slow
Speed: predict
Slow (O(n) per prediction)
Fast
Example
KNN, case-based reasoning
Neural Networks, Linear Regression, Decsion Trees
KNN is both Non-Parametric and Lazy. That combination makes it
simple, flexible, and interpretable — but slow at prediction and hungry
for clean, scaled features.
2.2 The Standard (Uniform) KNN Algorithm
In the standard version of the algorithm, all selected neighbors have an equal say in the prediction. For a query instance whose class we want to predict, the procedure is:
Choose an integer \(K\) representing the number of nearest neighbors.
Compute the distance between the query instance \(x_0\) and every training example.
Sort distances in ascending order and retain the \(K\) closest points (defining the neighborhood \(\mathcal{N}_0\)).
Gather the class labels of those \(K\) neighbors.
Return the simple majority class among the \(K\) neighbors as the prediction.
Formally, KNN computes the estimated conditional probability that a query observation \(x_0\) belongs to class \(j\) as the fraction of points in its \(K\)-nearest neighborhood \(\mathcal{N}_0\) whose response equals \(j\):
where \(I(y_i = j)\) is an indicator function that equals \(1\) if the \(i\)-th neighbor belongs to class \(j\), and \(0\) otherwise. The observation \(x_0\) is then assigned to the class \(j\) with the largest estimated conditional probability.
Classic k = 3 vs. k = 5 diagram
s*
2.3 Distance Metrics
A valid metric d must satisfy four axioms: non-negativity d(x1,x2) ≥ 0; self-proximity d(x,x) = 0; symmetry d(x1,x2) = d(x2,x1); and triangle inequality d(x1,x2) ≤ d(x1,x3) + d(x3,x2).
Euclidean
Manhattan
Minkowski
The Euclidean distance is the L2 norm, that is, the ordinary straight-line distance between two points in ℝⁿ.
It is the default metric for KNN in scikit-learn and matches the everyday notion of distance. It is also sensitive to feature scale, which is why the features must be standardized before it is used.
The Manhattan distance is the L1 norm, also called the city-block or taxicab distance. Instead of measuring a straight line, it adds the displacements along each axis.
The value of k controls the complexity of the model. A small k lets the prediction follow every local detail of the training data, while a large k produces a smoother decision boundary. The table below shows how this trade-off behaves across the range of k.
k
Model Complexity
Behavior
Risk
1 (very small)
Highest
Memorizes every training point; jagged decision boundary
Overfit — sensitive to noise and outliers
3, 5, 7 (odd)
High / Medium
Flexible, locally adaptive boundaries
Balanced (good default starting point)
≈ √n or 10–20% of n
Moderate
Smoother boundaries
Underfit risk starts growing
n (all points)
Lowest
Always predicts the majority class — a trivial baseline
Underfit — ignores all local structure
Practical rules of thumb
Start with odd k values to reduce ties in binary classification.
Pick k using cross-validation on the training set (not the test set!).
Larger datasets safely support larger k.
More complex/irregular data → lower optimum k.
2.5 Why Scaling Is Mandatory for KNN
KNN decides everything on the basis of distance, so a feature measured on a large numerical scale will dominate the distance calculation even when it is not the more informative feature. The following example shows how large this effect can be.
The Scaling Catastrophe
Consider two points: Age=28 vs. 38, Salary=$100,000 vs. $150,000. Euclidean distance without scaling:
The salary difference of $50K completely dominates the 10-year age difference. After standardization, each feature is measured in SD units and both contribute fairly to the distance.
2.6 KNN Decision Boundaries
The figure below illustrates KNN in action on a simple dataset with six blue and six orange observations.
Left: A test observation (black cross) is shown. With K = 3, the three closest points (inside the circle) are identified. Two are blue and one is orange → the query is predicted as blue.
Right: The KNN decision boundary for K = 3 is shown in black. The blue grid indicates the region where a test point would be classified as blue; the orange grid indicates the region where it would be classified as orange.
The choice of K has a drastic effect on the decision boundary as shown in the following diagrma:
K = 1: The boundary is jagged and highly flexible, following every training point closely. It captures noise and outliers, leading to overfitting.
K = 10: The boundary is smoother and more stable. It generalizes better, often producing a boundary close to the optimal one.
K = 100 (or very large): The boundary becomes too smooth — nearly linear or flat. It ignores local structure and underfits the data.
Key Insight: K Controls Boundary Flexibility
Small K → flexible, jagged boundaries, sensitive to noise (overfitting risk).
Large K → smooth, simple boundaries, ignores local patterns (underfitting risk).
The optimal K balances these two extremes, giving a boundary that captures true structure without memorizing noise.
2.6 The Equal-Vote Problem and Weighted KNN
In standard KNN each of the k neighbours gets exactly one vote, regardless of how far it is from the query point. This can produce counter-intuitive predictions, as shown below.
When “one neighbour, one vote” fails
Suppose k = 5 for a new query point. The neighbours of Class A are at distances {0.1, 5.0}; the neighbours of Class B are at {4.8, 4.9, 5.1}. Standard KNN counts 3 B vs 2 A and predicts B. Yet the closest neighbour (distance 0.1) clearly belongs to A, and that strong evidence is completely ignored.
The natural solution is distance-weighted voting: assign a weight to each neighbour that decreases with distance, then sum weights per class and predict the class with the largest total.
2.7 Formal Weighted KNN – The (K+1) Normalisation Approach
A well-known formulation from the literature (Weighted k-Nearest-Neighbor Techniques and Ordinal Classification, 2004) defines a weighted scheme in which the distances of the nearest neighbours are first scaled relative to the local neighbourhood. The algorithm is:
Weighted KNN using (K+1)-th neighbour for normalisation
Find K+1 nearest neighbours of the query point \(x\).
Let \(d(x, x_{(K+1)})\) be the distance to the \((K+1)\)-th neighbour. This distance provides a reference scale for the local neighbourhood.
For each of the first \(K\) neighbours, compute the normalised distance:
\[
D(i) = \frac{d(x, x_{(i)})}{d(x, x_{(K+1)})}.
\]
Because the first \(K\) neighbours are no farther away than the \((K+1)\)-th neighbour, these normalised distances satisfy \(0 \leq D(i) \leq 1\).
Apply a transformation function \(f(D)\) to obtain the weight:
\[
w_i = f\bigl(D(i)\bigr).
\]
The function is chosen so that closer neighbours receive greater weight. For example:
\(f(D) = 1/D\) (inverse distance – strongly emphasises close neighbours)
Predict using the weighted sum per class:
\[
\operatorname{argmax}_c \sum_{i \in \text{class } c} w_i.
\]
Important distinction: \(D(i)\) is a normalised distance, not the final weight. A smaller \(D(i)\) means that the neighbour is closer. The weighting function \(f\) then converts that distance into a weight, typically giving a larger weight to a smaller distance.
Key advantage: Normalising by the \((K+1)\)-th distance expresses each neighbour's distance relative to the local neighbourhood scale.
One particularly simple choice is inverse-distance weighting, where the weight is inversely proportional to the neighbour's distance:
$$
w_i = \frac{1}{d_i}.
$$
This is the weighting used by sklearn.neighbors.KNeighborsClassifier when weights='distance'.
At first glance, this may look different from the normalised formulation above. However, when the weighting function is \(f(D)=1/D\), the two forms are equivalent for classification. Since
$$
D(i)=\frac{d_i}{d_{K+1}},
$$
the inverse weight used in the 2004 formulation becomes
The factor \(d_{K+1}\) is the same for every one of the \(K\) neighbours. It therefore multiplies every weight by the same constant and does not change which class has the largest total weight. Thus, for inverse-distance weighting, we can equivalently use the much simpler formula
$$
\boxed{w_i=\frac{1}{d_i}}.
$$
Seeing the Equivalence with a Simple Example
Suppose K = 3, and the four nearest neighbours are at distances \(1, 2, 3,\) and \(4\). The fourth neighbour provides the \((K+1)\)-th distance used for normalisation.
Neighbour
Distance \(d_i\)
Normalised Distance \(D(i)=d_i/4\)
Inverse Weight \(1/D(i)\)
Simple Weight \(1/d_i\)
1st
1
0.25
4.000
1.000
2nd
2
0.50
2.000
0.500
3rd
3
0.75
1.333
0.333
Notice that the normalised distance is smallest for the closest neighbour. This is exactly what we expect: the closest neighbour has the smallest distance.
We then apply the inverse function \(1/D\). This reverses the ordering, so the smallest distance produces the largest weight:
Therefore, the two sets of weights have exactly the same relative ordering and produce the same class prediction. The normalisation changes the numerical values of the weights, but not the outcome of the weighted vote.
This equivalence is specific to inverse-distance weighting. With other functions, such as a triangular or Gaussian function, applying the function to the normalised distance \(d_i/d_{K+1}\) is generally not the same as applying it directly to the raw distance \(d_i\).
The customer example below uses the simple inverse-distance formulation because it is straightforward to compute and is the form used by scikit-learn for weights='distance'.
2.9 Worked Example – Weighted KNN in Action
Using the scaled customer dataset and query point David, with K = 3. As in the equivalence example above, we look one neighbour beyond K — the 4th nearest neighbour — purely to provide the standardising distance, not to vote.
Neighbour
Distance \(d_i\)
Standardised Distance \(D(i) = d_i / d_{(K+1)}\)
Similarity Weight \(1/D(i)\)
Class
John
0.349
0.362
2.759
Yes
Rachael
0.366
0.380
2.631
No
Norah
0.731
0.759
1.317
Yes
Jefferson
0.963
NA — used only to standardise
NA
No
Ruth
1.157
NA — outside K+1
NA
No
Standard KNN (counts, K=3): John (Yes), Rachael (No), Norah (Yes) → 2 Yes vs 1 No → predicts Yes.
Weighted KNN (sum of similarity weights):
Yes total = 2.759 + 1.317 = 4.077
No total = 2.631 = 2.631
The weighted prediction is Yes, and here it agrees with the simple majority vote — but the weighted scores show how much more strongly the evidence favours Yes than a simple 2-vs-1 count would suggest, since John and Norah's votes carry substantially higher weight than Rachael's alone.
Note: This example uses standardised distance (dividing by the (K+1)-th neighbour's distance) rather than raw \(1/d_i\), because the goal here is to demonstrate the general normalisation procedure that works for any kernel (triangular, Gaussian, etc.), not just the inverse-distance special case shown in Section 2.8's equivalence box. If you only ever plan to use \(1/d_i\) weighting, the standardisation step can be skipped, as shown earlier — but we keep it here to model the general-purpose workflow.
Why weighted voting can make the choice of k less sensitive: Because distant neighbours receive smaller weights, adding more distant neighbours does not necessarily give them the same influence they would have under equal voting. Thus, the effect of a large k can be reduced, although k remains an important hyperparameter.
2.10 Characteristics Summary of KNN
The strengths and weaknesses below follow directly from the properties discussed in this section: KNN is non-parametric and lazy, and it works entirely through distances.
✅ Super simple — no complex math.
✅ No assumptions about data distribution — handles non-linear boundaries naturally.
✅ Inherently supports multi-class and incremental learning.
Prediction is O(n) per query (slow on big training sets — fix with KD/ball trees).
Extremely sensitive to irrelevant features and feature scale.
Breaks down in high dimensions (curse of dimensionality — Chapter 5 topic).
3. Interactive Examples
Example 1: Classify a Point with k = 3 and k = 5
Given a tiny 2-D training set. Compute for yourself, then reveal.
Point
X
Y
Class
P1
0.3
0.7
A
P2
0.2
0.9
B
P3
0.6
0.6
A
P4
0.5
0.1
A
P5
0.7
0.7
B
P6
0.4
0.9
B
Query Q
0.2
0.6
?
Step 1: Compute Euclidean distances from Q to all 6 points (click)
(a) k = 3 neighbors: {A, B, B} → majority B → Predict Class B.
(b) k = 5 neighbors: {A, B, B, A, B} → 3 B, 2 A → Predict Class B.
Example 2: When Scaling Destroys the Distance
Scale-or-Not Scenario
Two features: house_sqft (range 800–4,000) and num_bedrooms (range 1–6).
House X: 1,200 sqft, 2 beds. House Y: 1,800 sqft, 3 beds.
Without any scaling, d(X,Y) ≈ √(600² + 1²) ≈ 600 — the bedroom difference is invisible.
What is the qualitative effect of applying Z-score standardization before distance?
If we used Manhattan distance instead of Euclidean on the raw values, would that help?
(a) Standardization rescales each feature to SD units. Typical SDs: sqft ≈ 700, bedrooms ≈ 1.2. SD units difference: sqft 600/700 ≈ 0.86 SD, bedrooms 1/1.2 ≈ 0.83 SD. After standardization, both features contribute approximately equally to the distance — exactly what we want.
(b) No. Manhattan on raw data still sums: 600 + 1 = 601. The bedroom difference still vanishes. All distance metrics need scale alignment when feature scales differ.
Example 3: Weighted KNN vs. Standard KNN
Query point Q. K = 5. Distances and classes of nearest 5: { d=0.05 A, d=0.98 B, d=0.99 B, d=1.00 B, d=1.01 A }.
Prediction of standard KNN?
Prediction of weighted KNN using w = 1 / d?
Why is there a difference? Which is more sensible?
(a) Standard KNN counts: 3 B vs. 2 A → Predict B.
(b) Weights: A gets 1/0.05 + 1/1.01 ≈ 20 + 0.99 = 20.99. B gets 1/0.98 + 1/0.99 + 1/1.00 ≈ 1.02 + 1.01 + 1.00 = 3.03. Weighted sum A > B → Predict A.
(c) Difference arises because that one extremely close neighbor at d = 0.05 is a very strong signal for A. Weighted KNN is more sensible here because it respects proximity. Always compare weights='uniform' vs. weights='distance' in cross-validation.
Note: we skip the K+1 normalization step here since w = 1/d is the special case where it's mathematically redundant — normalizing by the 6th neighbor would only rescale every weight by the same constant, leaving the ranking and prediction unchanged (see Section 2.8). For any other kernel, always normalize first.
4. Numerical Solutions
Problem 1: Manhattan, Euclidean, and Minkowski
Two 4-dimensional standardized points: p = [0.1, −0.3, 0.5, 0.0] and q = [0.3, 0.1, −0.2, 0.7]. Compute (a) Manhattan distance, (b) Euclidean distance, and (c) Minkowski distance with p = 3.
K = 4 (deliberately even, so ties can happen). Four nearest neighbors of a query: {d=0.2 → class 0, d=0.3 → class 1, d=0.5 → class 0, d=0.6 → class 1}.
Show that standard KNN gives a perfect 2/2 tie and describe two sensible tiebreakers.
Apply weighted KNN with w = 1 / d. Does this break the tie?
📘 Step-by-step solution
(a) Standard KNN counts: 2 votes for class 0, 2 votes for class 1 → tie 50/50. Common tiebreakers: (i) pick the class of the single nearest neighbor (class 0 wins); (ii) use weighted KNN; (iii) prefer the class with higher overall prior in the whole training set; (iv) randomly sample (weak!).
(b) Weights per neighbor: w(0@0.2) = 5; w(1@0.3) ≈ 3.333; w(0@0.5) = 2; w(1@0.6) ≈ 1.667. Sums: Class 0 total = 5 + 2 = 7; Class 1 total ≈ 3.333 + 1.667 = 5.00.
\( \text{Weighted class 0} = 7 > \text{Weighted class 1} = 5 \implies \text{Predict }\mathbf{0} \)
Yes — weighting cleanly resolves the tie in favor of the closer class-0 neighbors.
Note: we skip the K+1 normalization step here since w = 1/d is the special case where it's mathematically redundant — normalizing by the 5th neighbor would only rescale every weight by the same constant, leaving the ranking and prediction unchanged (see Section 2.8). For any other kernel, always normalize first.
Problem 3: Sensitivity of k – Overfitting vs. Underfitting by Hand
You have 8 training points, 2-D. Two are mislabeled noise: one red in a blue cluster, one blue in a red cluster. Answer qualitatively with justifications:
At k = 1, how do the two noisy points affect predictions in their immediate neighborhoods?
At k = 7, how do they affect predictions?
Which k value is more likely to overfit (memorize the noise)? Which is more likely to underfit (oversmooth and ignore local structure)?
📘 Step-by-step solution
(a) k = 1: The two mislabeled points each "own" a little Voronoi cell around themselves. Any query that lands nearer to them than to any correctly-labeled neighbor will be predicted wrong. The decision boundary becomes highly flexible and follows the training data very closely, making it extremely sensitive to local noise – this is the overfitting regime.
(b) k = 7 (out of 8): Every prediction is a near-majority vote over almost the whole dataset. The two noisy points contribute 2/7 of a vote to queries everywhere, shifting every prediction slightly but smoothly toward the wrong class. The decision boundary is very smooth but too simple – it fails to capture the true local cluster structure. This is the underfitting regime.
(c) k = 1 overfits – it memorizes the noise and produces erratic local predictions that are highly sensitive to individual points. k = 7 underfits – it oversmooths and ignores the meaningful local patterns in the data. The optimal k (e.g., 3 or 5) balances flexibility with smoothness, capturing the true structure without being overly sensitive to noise.
5. Try It Yourself
Problem 1 — Minkowski Distance Practice
Two points on a 2-D standardized plane: a = (1.0, −0.5), b = (2.0, 1.5).
Compute Minkowski distance at order p = 1, p = 2, and p = 3.
Verify numerically that d₁ ≥ d₂ ≥ d∞ on this example. Which metric most penalizes large individual coordinate errors?
(b) 3 ≥ 2.236 ≥ 2.080 ✓ holds. As p increases, the distance approaches the larger coordinate (2.0). Higher p values increasingly penalize the largest coordinate difference while reducing the influence of smaller differences. L2 (p=2) provides a balanced middle ground.
Problem 2 — Preprocessing Checklist for KNN
You are given an adult-income dataset with these features. For each column, say YES / NO / MAYBE for whether the described transformation should happen before KNN, with a one-sentence justification.
education_num (1 = Preschool through 16 = Doctorate) → Leave as is because it's already numeric?
native_country (42 countries) → One-hot encoding to 41 dummy columns?
Rows with missing occupation = ? → Drop rows?
YES. Continuous numeric feature; distance-based algorithm needs all features on SD scale.
NO. Never use LabelEncoder on nominal X features — it creates a fake ordering ("Private" < "Self-emp"?). One-hot encode instead.
MAYBE but still scale it. It is ordinal with known equal-ish steps, so leaving 1..16 is acceptable, but it should still be standardized along with the other numeric columns to avoid 16–1 range dominating SD-unit distances from age/income.
YES. Correct nominal encoding. (Bonus: 41 columns is high-dimensional for KNN, so consider pairing with chi-square feature selection later.)
MAYBE. If "?" is rare and not MCAR, impute or assign a dedicated Missing category + indicator rather than dropping the whole row.
Problem 3 — Weighted KNN with 1−D
We have K = 4 neighbors with distances to query: {1.0, 2.0, 3.0, 4.0}. The (K+1) = 5th neighbor's distance is 5.0 (used for normalization).
Compute normalized distances Dᵢ = dᵢ / dK+1 for i = 1..4.
Compute weights wᵢ = 1 − Dᵢ for each neighbor.
If neighbor classes are {C1, C2, C1, C2} respectively, which class wins the weighted vote?
Answer all 5 questions. Click an option for instant feedback.
Your score: 0 / 5
7. Key Takeaways
KNN is lazy + non-parametric. No training computation, no distributional assumptions, works on any shape of decision boundary — at the cost of slow O(n) predictions.
5-step algorithm: Choose K, compute all distances, sort, keep K nearest, return their majority class. That's the whole algorithm.
Distance metrics. Euclidean (L2) is the intuitive default; Manhattan (L1) is more outlier-robust; Minkowski generalizes both via order p.
K controls the flexibility-smoothness tradeoff. Small k → very flexible, follows training data closely, sensitive to noise, overfit risk. Large k → smoother decision boundaries, less sensitive to noise, underfit risk. Tune via cross-validation; use odd k to avoid 2-class ties.
Scale before KNN, always. Standardization (Z-score) usually beats Min-Max here. Skip scaling → the highest-range feature essentially becomes the only feature.
Weighted KNN fixes the equal-vote problem. Use w = 1/d, or w = 1−D normalized, or Gaussian kernels. sklearn parameter: weights='distance'.
Weighting is a safety net. It reduces the sensitivity to the exact value of k because distant neighbors' contributions naturally fade. Always compare weighted vs. uniform during model selection.
8. Common Pitfalls
Ignoring feature scaling. KNN is entirely distance-based. If you don't standardize, features with large ranges (e.g., salary in dollars) dominate the distance. Weighted KNN (`1/d`) makes this even worse, as an unscaled dominant feature completely distorts inverse-distance weights. Always scale before running KNN.
Choosing k using test-set performance. The test set should be used once, at the very end. If you use it to pick the best k, your reported accuracy will be overly optimistic. Pick k via cross-validation on the training set, then evaluate the final model once on the held-out test set.
Forgetting that prediction is O(n) per query. KNN stores all training data and computes distances to every point at prediction time. For large datasets, this becomes computationally expensive — a key limitation to consider when choosing KNN for a project.
Ignoring feature relevance and the curse of dimensionality. Every feature contributes equally to the distance calculation. Irrelevant features add noise and make neighbors less meaningful. In high dimensions, the curse of dimensionality makes distances converge, causing KNN to degenerate into a coin flip. Always perform feature selection or dimensionality reduction before applying KNN to high-dimensional data.
Setting k too large (e.g., k = n). This predicts the majority class for every query — useful only as a baseline. Any real dataset with local structure will be completely ignored, leading to severe underfitting.